﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using FinPlusCommon;
using log = Logger.Logger;
using u = FinPlusUtility.Utility;


namespace FinPlusComponents
{
    public class QLEngineIndexs : FinPlusComponent
    {
        private enum Params { IndexName, Date };
        private enum BuildEvents { Update, Refresh, UpdateAndRefresh }
        private readonly IFinPlusComp _indexBuildConn, _indexHistoryConn;
        private readonly QLAnalytics _analytics;
        private readonly BuildEvents _buildEvents;
        private readonly Indexs _indexs;

        public QLEngineIndexs(IFinPlusComp analytics, IFinPlusComp indexBuilds, IFinPlusComp indexHistorys, string buildEvents)
        {
            _analytics = (QLAnalytics)analytics;
            _indexBuildConn =indexBuilds;
            _indexHistoryConn = indexHistorys; 
            _buildEvents = u.EnumParse<BuildEvents>(buildEvents, BuildEvents.UpdateAndRefresh);
            _indexs = new Indexs();

            foreach (var indexBuild in _indexBuildConn.Adaptor.Values)
            {
                var indexName = indexBuild[Params.IndexName.ToString()].ToString();
                var indexHistory = _indexHistoryConn.Adaptor.Where("Name='IndexName' And Value='" + indexName + "'", Params.Date.ToString());
                _indexs.TryAdd(indexName, new Index(_analytics, indexName, indexBuild, indexHistory, _buildEvents));
            }

            IsValid = true;
        }

        //common control interface
        public override void Dispose() 
        {
            if (_indexBuildConn == null)
                _indexBuildConn.Dispose();

            if (_indexHistoryConn == null)
                _indexHistoryConn.Dispose();
        }

        //private
        private class Indexs : ConcurrentDictionary<string, Index> { }

        private class Index
        {
            private enum Params { IndexName, Instrument, LinkedCurve, CurveName, IndexType, Tenor, Date };
            
            private QLAnalytics _analytics;
            private IFunction _indexBuild;
            private string _indexName, _curveName, _indexType, _tenor;
            private IDictionary<string, IFunction> _indexHistory;
            private BuildEvents _buildEvents;

            public Index(QLAnalytics analytics, string indexName, IFunction indexBuild, IDictionary<string, IFunction> indexHistory, BuildEvents buildEvents)
            {
                _analytics = analytics;
                _indexName = indexName;
                _indexBuild = indexBuild;
                _indexHistory = indexHistory;
                _curveName = indexBuild[Params.CurveName.ToString()].ToString();
                _indexType = indexBuild[Params.IndexType.ToString()].ToString();
                _tenor = indexBuild[Params.Tenor.ToString()].ToString();
                _buildEvents = buildEvents;
                BuildIndex();
            }

            private void BuildIndex()
            {
                try
                {
                    lock (_analytics.QL)
                       _analytics.QL.Index(_analytics.MarketName, _curveName, _indexName, _indexType, _tenor, "");//TODO
                }
                catch (Exception e)
                {
                    log.Log(Logger.Level.Error, e.Message, e);
                }
            }
        }
    }
}
